package logic

import (
	"context"
	"fmt"
	"github.com/google/uuid"
	"google.golang.org/grpc/peer"
	"strings"
	healthClient "zxs-micro-2/zxs-micro-healthutil/client"
	"zxs-micro-2/zxs-micro-proto/serverfindpb/serverfind"
	"zxs-micro-2/zxs-micro-serverfind-server/data"
	"zxs-micro-2/zxs-micro-serverfind-server/report"
)

func AddNewServerLogic(ctx context.Context, serviceType, servicePort, protocol string) (*serverfind.AddServerResponse, error) {
	p, ok := peer.FromContext(ctx)
	if !ok {
		return nil, report.NOT_FROM_GRPC_ERROR
	}
	//通过Addr方法获取的地址会带上客户端的port，然而此处port并不是服务端口，因此需要移除
	ip := strings.Split(p.Addr.String(), ":")[0]
	id := uuid.New().String()
	serverData := data.GetServerDataInterface("")
	serverData.AddNewServer(id, ip+servicePort, serviceType, protocol)
	rsp := new(serverfind.AddServerResponse)
	rsp.ServerId = id
	if servicePort == "-1" {
		//表示该服务不需要被服务发现管理，所以不需要新增健康检查等功能
		return rsp, nil
	}
	healthClient.WatchHealthServer(ip+servicePort, getHealthWatcherErrorHandler(id, serverData))
	fmt.Println(fmt.Sprintf("添加了一个[%s]类型的服务，地址在[%s]，id=%s", serviceType, ip+servicePort, id))
	return rsp, nil
}

func QueryServerListByTypeLogic(ctx context.Context,
	queryType string) (*serverfind.QueryServerListByTypeResponse, error) {
	serverData := data.GetServerDataInterface("")
	ss := serverData.GetServerListByType(queryType)
	rsp := new(serverfind.QueryServerListByTypeResponse)
	rsp.ServerList = make([]*serverfind.ServerStruct, len(ss))
	for i, o := range ss {
		rsp.ServerList[i] = o.ToPb()
	}
	return rsp, nil
}

func ServerDownLogic(ctx context.Context, id string) {
	serverData := data.GetServerDataInterface("")
	serverData.DeleteServer(id)
}

func QueryServerListByIdsLogic(ctx context.Context,
	ids []string) (*serverfind.QueryServerListByIdsResponse, error) {
	serverData := data.GetServerDataInterface("")
	services := serverData.GetServerListByIds(ids)
	rsp := new(serverfind.QueryServerListByIdsResponse)
	rsp.ServerList = make([]*serverfind.ServerStruct, len(services))
	for i, o := range services {
		rsp.ServerList[i] = o.ToPb()
	}
	return rsp, nil
}

func getHealthWatcherErrorHandler(serverId string, dataStore data.ServerDataIntf) func() {
	return func() {
		dataStore.DeleteServer(serverId)
	}
}
